package com.wofish.core.aspectj;

import com.wofish.core.annotation.ParamValid;
import com.wofish.core.dto.JsonRsp;
import com.wofish.core.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.List;

/**
 * @Author yubin
 * @Description //TODO
 * @Date 2019-05-11 00:16
 */

@Slf4j
@Aspect
@Component
public class ParamValidAspect {


    @Around("@annotation(paramValid)")
    public Object paramValid(ProceedingJoinPoint pjp, ParamValid paramValid) throws Throwable{
        boolean flag = true;
        Object[] paramObj = pjp.getArgs();
        if (paramObj.length > 0) {
            if (paramObj[1] instanceof BindingResult) {
                BindingResult result = (BindingResult) paramObj[1];
                JsonRsp errorMap = this.validRequestParams(result);
                if (errorMap != null && errorMap.getCode() == 1) {
                    ServletRequestAttributes res = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                    HttpServletResponse response = res.getResponse();
                    response.setCharacterEncoding("UTF-8");
                    response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
                    response.setStatus(HttpStatus.BAD_REQUEST.value());

                    OutputStream output = null;
                    try {
                        output = response.getOutputStream();
                        String error = JsonUtil.objToStr(errorMap);
                        flag = false;
                        log.info("aop check method:{},检测到参数不规范:{}",pjp.getSignature(), error);
                        output.write(error.getBytes("UTF-8"));

                    } catch (Throwable e) {
                        log.error(e.getMessage());
                    } finally {
                        try {
                            if (output != null) {
                                output.close();
                            }
                        } catch (Exception e) {
                            log.error(e.getMessage());
                        }
                    }
                }
            }
        }
        return flag?pjp.proceed():null;
    }

    /**
     * 校验
     */
    protected JsonRsp validRequestParams(BindingResult result){
        JsonRsp jsonRsp = new JsonRsp();
        if (result.hasErrors()) {
            List<ObjectError> list = result.getAllErrors();
            for (ObjectError error : list) {
                jsonRsp.setCode(1);
                jsonRsp.setMsg(error.getDefaultMessage());//验证信息
                return jsonRsp;
            }
        }
        return jsonRsp;
    }
}

